package rsa

import (
	"crypto/rand"
	"crypto/rsa"
	"crypto/x509"
	"encoding/base64"
	"encoding/pem"
)

/*
	使用rsa 非对称加密算法，进行加密解密，已实现公钥加密，私钥解密
	使用方式，先在不同的平台上生成公钥和私钥，然后利用公钥进行数据的加密；
	然后得到生成的加密串，再把加密串使用私钥进行解密即可得到对应的数据;

	公钥和私钥是成对生成的，但是不同的系统生成的不一样，正常在linux系统下生成即可
*/

//公开

type Public interface {
	i()
	Encrypt(encryptStr string) (string, error) //Encrypt加密
}

//私有

type Private interface {
	i()
	Decrypt(decryptStr string) (string, error) //Decrypt解密
}

type rsaPub struct {
	PublicKey string //设置为常量或者从文件中读取
}

type rsaPri struct {
	PrivateKey string ////设置为常量或者从文件中读取
}

func NewPublic(publicKey string) Public {
	return &rsaPub{PublicKey: publicKey}
}

func (r *rsaPub) i() {
}

// Encrypt 公钥加密
func (r *rsaPub) Encrypt(encryptStr string) (string, error) {
	// pem 解码
	block, _ := pem.Decode([]byte(r.PublicKey))

	//x509 解码
	publicKeyInterface, err := x509.ParsePKIXPublicKey(block.Bytes)
	if err != nil {
		return "", err
	}

	//类型断言
	publicKey := publicKeyInterface.(*rsa.PublicKey)

	//对明文进行加密
	encryptedStr, err := rsa.EncryptPKCS1v15(rand.Reader, publicKey, []byte(encryptStr))
	if err != nil {
		return "", err
	}
	//返回密文
	return base64.URLEncoding.EncodeToString(encryptedStr), nil
}

func NewPrivate(privateKey string) Private {
	return &rsaPri{PrivateKey: privateKey}
}

func (r *rsaPri) i() {
}

func (r *rsaPri) Decrypt(decryptStr string) (string, error) {
	// pem 解码
	block, _ := pem.Decode([]byte(r.PrivateKey))
	// X509 解码
	privateKey, err := x509.ParsePKCS1PrivateKey(block.Bytes)
	if err != nil {
		return "", err
	}
	decryptBytes, err := base64.URLEncoding.DecodeString(decryptStr)

	//对密文进行解密
	decrypted, _ := rsa.DecryptPKCS1v15(rand.Reader, privateKey, decryptBytes)

	//返回明文
	return string(decrypted), nil
}
